#include<math.h>
#include"fraction.h"

fraction::fraction()
{
    numerator = 0;
    denominator = 1;
}

fraction::fraction(int nume, int deno) {
    numerator = nume;
    denominator = deno;
}

fraction::fraction(int nume) {
    numerator = nume;
    denominator = 1;
}

fraction fraction::gcdlcm(int _a, int _b) {
    int GCD, LCM, k = 0, p, q;
    int a = abs(_a), b = abs(_b);
    int sign = 1;
    if (_a * _b < 0) {
        sign = -1;
    }
    fraction x;
    if (a != 0) {
        int min = a < b ? a : b, max = a > b ? a : b;
        for (int i = min; i > 0; i--) {
            if (max % i == 0&& min % i == 0) {
                GCD = i;
                break;
            }
        }
        LCM = a * b / GCD;
        x.numerator = GCD;
        x.denominator = sign * LCM;
        return x;
    }
    else {
        x = fraction(a, b);
        return x;
    }
}

fraction fraction::operator+(fraction a) {
    fraction d = gcdlcm(a.denominator, this->denominator);
    fraction f;
    f.denominator = d.denominator;
    f.numerator = a.numerator * (f.denominator / a.denominator) + this->numerator * (f.denominator / this->denominator);
    fraction e = gcdlcm(f.numerator, f.denominator);
    if (e.numerator != 0) {
        f.denominator /= e.numerator;
        f.numerator /= e.numerator;
    }
    else {
        f.denominator = 1;
    }
    int v = abs(f.denominator), w = abs(f.numerator);
    int sign = 1;
    if (f.denominator * f.numerator < 0) {
        sign = -1;
    }
    else {
        f.numerator=w;
        f.denominator = v * sign;
    }
    return f;
}

fraction fraction::operator+=(fraction a)
{
    *this = *this + a;
    return *this;
}

fraction fraction::operator-(fraction a) {
    fraction d = gcdlcm(a.denominator, this->denominator);
    fraction f;
    f.denominator = d.denominator;
    f.numerator = this->numerator * (f.denominator / this->denominator) - a.numerator * (f.denominator / a.denominator);
    fraction e = gcdlcm(f.numerator, f.denominator);
    if (e.numerator != 0) {
        f.denominator /= e.numerator;
        f.numerator /= e.numerator;
    }
    else {
        f.denominator = 1;
    }
    int v = abs(f.denominator), w = abs(f.numerator);
    int sign = 1;
    if (f.denominator * f.numerator < 0) {
        sign = -1;
    }
    else {
        f.numerator = w * sign;
        f.denominator = v;
    }
    return f;
}

fraction fraction::operator-=(fraction a)
{
    *this = *this - a;
    return *this;
}

fraction fraction::operator*(fraction a) {
    fraction f;
    f.denominator = this->denominator * a.denominator;
    f.numerator = this->numerator * a.numerator;
    if (f.numerator == 0) {
        f.denominator = 1;
    }
    int v = abs(f.denominator), w = abs(f.numerator);
    int sign = 1;
    if (f.denominator * f.numerator < 0) {
        sign = -1;
    }
    else {
        f.numerator = w * sign;
        f.denominator = v;
    }
    return f.simplify();
}
fraction fraction::operator*(int a) {
    fraction f;
    f.denominator = this->denominator;
    f.numerator = this->numerator * a;
    if (f.numerator == 0) {
        f.denominator = 1;
    }
    int v = abs(f.denominator), w = abs(f.numerator);
    int sign = 1;
    if (f.denominator * f.numerator < 0) {
        sign = -1;
    }
    else {
        f.numerator = w * sign;
        f.denominator = v;
    }
    return f.simplify();
}

fraction fraction::operator*=(fraction a)
{
    *this = *this * a;
    return *this;
}

fraction fraction::operator/(fraction a) {
    fraction f;
    f.denominator = this->denominator * a.numerator;
    f.numerator = this->numerator * a.denominator;
    if (f.numerator == 0) {
        f.denominator = 1;
    }
    int v = abs(f.denominator), w = abs(f.numerator);
    int sign = 1;
    if (f.denominator * f.numerator < 0) {
        sign = -1;
    }
    else {
        f.numerator = w * sign;
        f.denominator = v;
    }
    return f.simplify();
}

fraction fraction::operator/=(fraction a)
{
    *this = *this / a;
    return *this;
}

fraction fraction::simplify() {
    int gcd = gcdlcm(this->numerator, this->denominator).numerator;
    if (gcd != 0) {
        this->numerator /= gcd;
        this->denominator /= gcd;
    }
    return *this;
}